package managedbean;

import java.io.IOException;
import java.io.Serializable;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.primefaces.model.MenuModel;
import session.stateless.StaffAccountManagerLocal;
import session.stateless.SystemMessagesLocal;
import util.entityhelper.StaffAccountState;
import util.generator.StaffMenuGenerator;
import util.localization.WebLocalization;


@ManagedBean
@RequestScoped
public class StaffLoginManagedBean implements Serializable {

    @EJB
    private StaffAccountManagerLocal staffAccountMgr;
    // EXCEPTION
    @EJB
    private SystemMessagesLocal systemMessages;
    
    private FacesContext ctx = FacesContext.getCurrentInstance();
    private WebLocalization localization;
    
    //  user preferred locale
    private String preferredLocale;
    
    
    // other fields from database
    private String username;
    private String password;
//    private StaffAccountState staffAccountState;
    private boolean remember;
    private String r;
    private MenuModel model;

    /** Creates a new instance of StaffLoginManagedBean */
    public StaffLoginManagedBean() {
        checkCookie();

        /* LOCALIZATION */
        localization = new WebLocalization();
        preferredLocale = localization.getPreferredLocaleFromSession();
        /* END LOCALIZATION */
    }

    public void doLogin(ActionEvent event) {
        try {
            // set language for all MANAGERS for all THROWABLE EXCEPTIONS in backend
            // to use this line everytime language changes
            staffAccountMgr.setSelectedLocale(preferredLocale);

            StaffAccountState staffAccountState = null;
            try {
                staffAccountState = staffAccountMgr.getStaffAccountByUsername(username);
            }
            catch (Exception ex) {
                // do nothing, just let the system catch any exception and continue to next part for catching of null
            }
            
            if (staffAccountState == null) {
                String statusMessage = systemMessages.getSystemMessage("STAFF_ACCT_DOES_NOT_EXIST", preferredLocale);
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, statusMessage, ""));
            } else {
                // TODO: i moved the menu to view page instead lol
            
                if (staffAccountState.getPassword().equals(password)) {
                    // Save the userid and password in a cookie
                    Cookie usernameCookie = new Cookie("usernameCookie", username);
//                    Cookie passwordCookie = new Cookie("passwordCookie", password);
                    if (remember == false) {
                        r = "false";
                    } else {
                        r = "true";
                    }
                    Cookie rememberCookie = new Cookie("rememberCookie", r);
                    usernameCookie.setMaxAge(3600);
//                    passwordCookie.setMaxAge(3600);

                    ((HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse()).addCookie(usernameCookie);
//                    ((HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse()).addCookie(passwordCookie);
                    ((HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse()).addCookie(rememberCookie);

                    /* LOCALIZATION */
                    // first thing after set cookie is to save details to session! and do whatever required first                        
                    // now after login, replace preferred language with SAVED LANGUAGE in database
                    preferredLocale = staffAccountState.getStaff().getLocale();
                    // set language for related backend MANAGERS for all THROWABLE EXCEPTIONS from now on in
                    // backend if message is not sent from frontend to backend through SystemMessages
                    // to use this line everytime having possible language changes
                    staffAccountMgr.setSelectedLocale(preferredLocale);
                    /* END LOCALIZATION */

                    // now set all required stuff to SESSION here...create session if required...
                    // check if session has anything..default values if nothing
                    if (ctx.getExternalContext().getSessionMap().isEmpty()) {
                        // create a session if no session created. get whatever user uses currently
                        ctx.getExternalContext().getSession(true);
                        // saved preferredLocale (from database) to session; value used to set values in constructors
                        ctx.getExternalContext().getSessionMap().put("savedLocale", preferredLocale);
                        System.out.println("session setting lOCALE:" + ctx.getExternalContext().getSessionMap().get("savedLocale"));
                        ctx.getExternalContext().getSessionMap().put("staffAccountId", staffAccountState.getId());
                        System.out.println("session setting lOCALE:" + ctx.getExternalContext().getSessionMap().get("staffAccountId"));
                    }
                    else {
                        // saved preferredLocale (from database) to session; value used to set values in constructors
                        localization.putSavedLocaleToSession(preferredLocale);
//                        System.out.println("session setting lOCALE:" + ctx.getExternalContext().getSessionMap().get("savedLocale"));
                        ctx.getExternalContext().getSessionMap().put("staffAccountId", staffAccountState.getId());
//                        System.out.println("session setting lOCALE:" + ctx.getExternalContext().getSessionMap().get("staffAccountId"));
//                        ctx.getExternalContext().getSessionMap().put("staffMenuModel", model);
                    }



                    // EXCEPTION
//                    String statusMessage = systemMessages.getSystemMessage("LOGIN_SUCCESS", preferredLocale);
//                    FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, statusMessage, ""));

//                    FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("Account", staffState);

                    // redirection upon success
                    String serverName = FacesContext.getCurrentInstance().getExternalContext().getRequestServerName();
                    // force normal http
                    String serverPort = "8080";
                    // the project name /Tourism-war
                    String contextPath = FacesContext.getCurrentInstance().getExternalContext().getRequestContextPath();
                    FacesContext.getCurrentInstance().getExternalContext().redirect("http://" + serverName + ":" + serverPort + contextPath + "/staff/ViewStaffAccount.xhtml");
                } 
                else 
                {
                    // EXCEPTION
                    String statusMessage = systemMessages.getSystemMessage("LOGIN_INCORRECT", preferredLocale);
                    FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, statusMessage, ""));
                }
            }
        }
        catch (IOException ex) {
            // EXCEPTION
            String statusMessage = systemMessages.getSystemMessage("REDIRECT_FAIL", preferredLocale);
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, statusMessage, ""));
        }
    }

    public void checkCookie() {
        String cookieName = null;
        Cookie cookie[] = ((HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest()).getCookies();
        if (cookie != null && cookie.length > 0) {
            for (int i = 0; i < cookie.length; i++) {
                cookieName = cookie[i].getName();
                if (cookieName.equals("usernameCookie")) {
                    username = cookie[i].getValue();
//                } else if (cookieName.equals("passwordCookie")) {
//                    password = cookie[i].getValue();
                } else if (cookieName.equals("rememberCookie")) {
                    r = cookie[i].getValue();
                    if (r.equals("false")) {
                        setRemember(false);
                    } else if (r.equals("true")) {
                        setRemember(true);
                    }
                }
            }
        } else {
            System.out.println("Cannot find any cookie");
        }
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public boolean getRemember() {
        return remember;
    }

    public void setRemember(boolean remember) {
        this.remember = remember;
    }

    public SystemMessagesLocal getSystemMessages() {
        return systemMessages;
    }

    public void setSystemMessages(SystemMessagesLocal systemMessages) {
        this.systemMessages = systemMessages;
    }

    public StaffAccountManagerLocal getStaffAccountMgr() {
        return staffAccountMgr;
    }

    public void setTouristAccountMgr(StaffAccountManagerLocal staffAccountMgr) {
        this.staffAccountMgr = staffAccountMgr;
    }

    public FacesContext getCtx() {
        return ctx;
    }

    public void setCtx(FacesContext ctx) {
        this.ctx = ctx;
    }

    public String getPreferredLocale() {
        return preferredLocale;
    }

    public void setPreferredLocale(String preferredLocale) {
        this.preferredLocale = preferredLocale;
    }

    public String getR() {
        return r;
    }

    public void setR(String r) {
        this.r = r;
    }

    public WebLocalization getLocalization() {
        return localization;
    }

    public void setLocalization(WebLocalization localization) {
        this.localization = localization;
    }

    /**
     * @return the model
     */
    public MenuModel getModel() {
        return model;
    }

    /**
     * @param model the model to set
     */
    public void setModel(MenuModel model) {
        this.model = model;
    }
}
